package com.cyh.testcustomui;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.util.Log;
import android.widget.TextView;

import androidx.annotation.Nullable;

import android.annotation.SuppressLint;
@SuppressLint("AppCompatCustomView")


public class A1TextView extends TextView {
    private static final String TAG = "A1TextView";

    private String m_a1text;
    private int m_alcolor;
    private int m_a1size;
    private int m_a1length;
    private Drawable m_a1back;
    private int m_id_alback;
    private int m_a1Type;

    private Paint mPaint;
    /**
     * 代码中新建对象时调用
     * */
    public A1TextView(Context context) {
        //这个是this, 而不是默认的supper
        this(context, null);
        //Log.i(TAG, "----------代码中新建对象时调用");
    }

    /**
     * 布局layout中使用时调用
     * */
    public A1TextView(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
        //Log.i(TAG, "----------布局layout中使用时调用");
    }

    /**
     * 布局layout中使用时调用，但会有style
     * */
    public A1TextView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        //Log.i(TAG, "----------布局layout中使用时调用，但会有style");

        /**
         * getDimension()是基于当前DisplayMetrics进行转换，获取指定资源id对应的尺寸。文档里并没说这里返回的就是像素，
         *               要注意这个函数的返回值是float，像素肯定是int。
         * getDimensionPixelSize()与getDimension()功能类似，不同的是将结果转换为int，并且小数部分四舍五入。
         * getDimensionPixelOffset()与getDimension()功能类似，不同的是将结果转换为int，并且偏移转换（offset conversion，
         *              函数命名中的offset是这个意思）是直接截断小数位，即取整（其实就是把float强制转化为int，注意不是四舍五入哦）。
         *
         * 由此可见，这三个函数返回的都是绝对尺寸，而不是相对尺寸（dp/sp等）。如果getDimension()返回结果是20.5f，
         * 那么getDimensionPixelSize()返回结果就是21，getDimensionPixelOffset()返回结果就是20。
         *
         * 在java代码里很多setWidth()，setHeight()的参数都是像素，即整形，大家根据实际情况，看看如果是四舍五入就调用getDimensionPixelSize()，
         * 如果是取整就调用getDimensionPixelOffset()。千万不要setWidth((int)getDimension()) 这么写哦！
         *
         * */

        /**
         * getInteger: 表示integer类型
         * getInt: 一般表示枚举类型
         * */
        TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.A1TextView);
        m_a1text = array.getString(R.styleable.A1TextView_a1text);
        m_alcolor = array.getColor(R.styleable.A1TextView_a1color, Color.parseColor("#000000"));
        m_a1size = array.getDimensionPixelSize(R.styleable.A1TextView_a1size, 0);
        //int 类型
        m_a1length = array.getInteger(R.styleable.A1TextView_a1length, 0);
        m_a1back = array.getDrawable(R.styleable.A1TextView_a1back);
        m_id_alback = array.getResourceId(R.styleable.A1TextView_a1back, 0);
        //枚举类型
        m_a1Type = array.getInt(R.styleable.A1TextView_a1Type, 0);



        Log.i(TAG, "----------a1Text=" + m_a1text);
        Log.i(TAG, "----------alcolor=" + m_alcolor);
        Log.i(TAG, "----------a1size=" + m_a1size);
        Log.i(TAG, "----------a1length=" + m_a1length);
        Log.i(TAG, "----------a1back=" + m_a1back);
        Log.i(TAG, "----------id_alback=" + m_id_alback);
        Log.i(TAG, "----------a1Type=" + m_a1Type);
        array.recycle();

        mPaint = new Paint();
        mPaint.setAntiAlias(true);
        mPaint.setTextSize(m_a1size);
        mPaint.setColor(m_alcolor);

    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);

        //获取宽高模式
        int widthMode = MeasureSpec.getMode(widthMeasureSpec);
        int heightMode = MeasureSpec.getMode(heightMeasureSpec);
        Log.i(TAG, "-------获取宽高模式：widthMode = " + widthMode + ", heightMode = " + heightMode);

        if(widthMode == MeasureSpec.AT_MOST) {
            //宽使用的是wrap_content
            Log.i(TAG, "-------宽使用的是wrap_content");
        }

        if(widthMode == MeasureSpec.EXACTLY) {
            //宽使用的是确切的值:match_parent、或具体的值
            Log.i(TAG, "-------宽使用的是确切的值:match_parent、或具体的值");
        }

        if(widthMode == MeasureSpec.UNSPECIFIED) {
            //尽可能大的值， 父布局中用到ScrollView、ListView；很少用到
            Log.i(TAG, "-------尽可能大的值， 父布局中用到ScrollView、ListView；很少用到");
        }


        //1.确定的值， 这个时候不要计算，给的多少就多少
        int width = MeasureSpec.getSize(widthMeasureSpec);
        int height = MeasureSpec.getSize(heightMeasureSpec);

        //2.给的是wrap_content, 需要计算

        if(widthMode == MeasureSpec.AT_MOST) {
            Rect bounds = new Rect();
            mPaint.getTextBounds(m_a1text, 0, m_a1text.length(), bounds);
            width = bounds.width() + getPaddingLeft() + getPaddingRight();
        }
        if(heightMode == MeasureSpec.AT_MOST) {
            Rect bounds = new Rect();
            mPaint.getTextBounds(m_a1text, 0, m_a1text.length(), bounds);
            height = bounds.height() + getPaddingBottom() + getPaddingTop();
        }

        //3.设置控件的宽高
        setMeasuredDimension(width, height);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        //绘制文字的y轴坐标应该是基线坐标
        //top是最顶上的线（文字不会绘制到这里来）
        //asect是第二条线，文字最高可以绘制到这里
        //mid 是中心线
        //baseline 是基线
        // descent 倒数第二条线， 文字最底能绘制的线
        // bottom 最底下的那条线， 文字不会绘制到这里。

        Paint.FontMetricsInt fontMetricsInt = mPaint.getFontMetricsInt();
        int top = fontMetricsInt.top;
        int ascent = fontMetricsInt.ascent;
        int descent = fontMetricsInt.descent;
        int bottom = fontMetricsInt.bottom;
        int leading = fontMetricsInt.leading;
        Log.i(TAG, "----文字top = " + top); //-15
        Log.i(TAG, "----文字ascent = " + ascent); //-13
        Log.i(TAG, "----文字descent = " + descent); //3
        Log.i(TAG, "----文字bottom = " + bottom); //4
        Log.i(TAG, "----文字leading = " + leading); //0

        int dy = (bottom - top)/2 - bottom;   //这个计算的是中线与基线直接的距离
        int baseLine = getHeight()/2 + dy; //中线再加上这一段距离就是坐标了。


        int x = getPaddingLeft();
        canvas.drawText(m_a1text, 0, baseLine, mPaint);

    }
}
